package ten;

public class SafeTest01 {
    public static void main(String[] args) {
        Runnable r = new SafeWeb12306();
        new Thread(r, "ct1").start();
        new Thread(r, "ct2").start();
        new Thread(r, "ct3").start();
    }
}

class SafeWeb12306 implements Runnable {

    private boolean flag = true;
    private int ticketNums = 100;

    @Override
    public void run() {
        while (flag) {
//            test01();
//            test02();
//            test03();
//            test04();
            test05();
        }
    }

    private synchronized void test01() {
        if (ticketNums <= 0) {
            flag = false;
            return;
        }
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "--->" + ticketNums--);
    }

    private void test02() {
        synchronized (this) {
            if (ticketNums <= 0) {
                flag = false;
                return;
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "--->" + ticketNums--);
        }
    }

    //不安全
    private void test03() {
        synchronized ((Integer) ticketNums) {
            if (ticketNums <= 0) {
                flag = false;
                return;
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "--->" + ticketNums--);
        }
    }

    //不安全
    private void test04() {
        synchronized (this) {
            if (ticketNums <= 0) {
                flag = false;
                return;
            }
        }
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "--->" + ticketNums--);
    }

    //安全
    //double checking
    private void test05() {
        if (ticketNums <= 0) {
            flag = false;
            return;
        }
        synchronized (this) {
            if (ticketNums <= 0) {
                flag = false;
                return;
            }

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "--->" + ticketNums--);
        }
    }
}
